﻿using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;
namespace LitTools
{
    /// <summary>
    /// 观察拓展
    /// </summary>
    public static class ObserverExt
    {
        #region 3D碰撞器
        /// <summary>
        /// 3D碰撞器进入
        /// </summary>
        /// <param name="collider"></param>
        /// <param name="act"></param>
        public static void AddCollisionEnter(this Collider collider, Action<Collision> act)
        {
            if (!collider.gameObject.TryGetComponent<ColliderObserver>(out var observer))
            {
                observer = collider.gameObject.AddComponent<ColliderObserver>();
            }
            observer.OnCollisionEnterAct += act;
        }

        public static void SubCollisionEnter(this Collider collider, Action<Collision> act)
        {
            if (!collider.gameObject.TryGetComponent<ColliderObserver>(out var observer))
                return;
            observer.OnCollisionEnterAct -= act;
        }

        public static void ClearCollisionEnter(this Collider collider)
        {
            if (!collider.gameObject.TryGetComponent<ColliderObserver>(out var observer))
                return;
            observer.OnCollisionEnterAct = null;
        }
        /// <summary>
        /// 3D碰撞器保持
        /// </summary>
        /// <param name="collider"></param>
        /// <param name="act"></param>
        public static void OnCollisionStay(this Collider collider, Action<Collision> act)
        {
            if (!collider.gameObject.TryGetComponent<ColliderObserver>(out var observer))
            {
                observer = collider.gameObject.AddComponent<ColliderObserver>();
            }
            observer.OnCollisionStayAct += act;
        }
        /// <summary>
        /// 3D碰撞器退出
        /// </summary>
        /// <param name="collider"></param>
        /// <param name="act"></param>
        public static void OnCollisionExit(this Collider collider, Action<Collision> act)
        {
            if (!collider.gameObject.TryGetComponent<ColliderObserver>(out var observer))
            {
                observer = collider.gameObject.AddComponent<ColliderObserver>();
            }
            observer.OnCollisionExitAct += act;
        }
        #endregion

        #region 3D触发器
        /// <summary>
        /// 3D碰撞器进入
        /// </summary>
        /// <param name="collider"></param>
        /// <param name="act"></param>
        public static void OnTriggerEnter(this Collider collider, Action<Collider> act)
        {
            if (!collider.gameObject.TryGetComponent<TriggerObserver>(out var observer))
            {
                observer = collider.gameObject.AddComponent<TriggerObserver>();
            }
            observer.OnTriggerEnterAct += act;
        }
        /// <summary>
        /// 3D碰撞器保持
        /// </summary>
        /// <param name="collider"></param>
        /// <param name="act"></param>
        public static void OnTriggerStay(this Collider collider, Action<Collider> act)
        {
            if (!collider.gameObject.TryGetComponent<TriggerObserver>(out var observer))
            {
                observer = collider.gameObject.AddComponent<TriggerObserver>();
            }
            observer.OnTriggerStayAct += act;
        }
        /// <summary>
        /// 3D碰撞器退出
        /// </summary>
        /// <param name="collider"></param>
        /// <param name="act"></param>
        public static void OnTriggerExit(this Collider collider, Action<Collider> act)
        {
            if (!collider.gameObject.TryGetComponent<TriggerObserver>(out var observer))
            {
                observer = collider.gameObject.AddComponent<TriggerObserver>();
            }
            observer.OnTriggerExitAct += act;
        }
        #endregion

        #region 2D碰撞器
        /// <summary>
        /// 2D碰撞器进入
        /// </summary>
        /// <param name="collider2D"></param>
        /// <param name="act"></param>
        public static void OnCollider2DEnter(this Collider2D collider2D, Action<Collision2D> act)
        {
            if (!collider2D.gameObject.TryGetComponent<Collider2DObserver>(out var observer))
            {
                observer = collider2D.gameObject.AddComponent<Collider2DObserver>();
            }
            observer.OnCollision2DEnterAct += act;
        }
        /// <summary>
        /// 2D碰撞器保持
        /// </summary>
        /// <param name="collider2D"></param>
        /// <param name="act"></param>
        public static void OnCollider2DStay(this Collider2D collider2D, Action<Collision2D> act)
        {
            if (!collider2D.gameObject.TryGetComponent<Collider2DObserver>(out var observer))
            {
                observer = collider2D.gameObject.AddComponent<Collider2DObserver>();
            }
            observer.OnCollision2DStayAct += act;
        }
        /// <summary>
        /// 2D碰撞器离开
        /// </summary>
        /// <param name="collider2D"></param>
        /// <param name="act"></param>
        public static void OnCollider2DExit(this Collider2D collider2D, Action<Collision2D> act)
        {
            if (!collider2D.gameObject.TryGetComponent<Collider2DObserver>(out var observer))
            {
                observer = collider2D.gameObject.AddComponent<Collider2DObserver>();
            }
            observer.OnCollision2DExitAct += act;
        }
        #endregion

        #region 2D触发器
        /// <summary>
        /// 2D触发器进入
        /// </summary>
        /// <param name="collider"></param>
        /// <param name="act"></param>
        public static void OnTrigger2DEnter(this Collider collider, Action<Collider2D> act)
        {
            if (!collider.gameObject.TryGetComponent<Trigger2DObserver>(out var observer))
            {
                observer = collider.gameObject.AddComponent<Trigger2DObserver>();
            }
            observer.OnTrigger2DEnterAct += act;
        }
        /// <summary>
        /// 2D触发器保持
        /// </summary>
        /// <param name="collider"></param>
        /// <param name="act"></param>
        public static void OnTrigger2DStay(this Collider collider, Action<Collider2D> act)
        {
            if (!collider.gameObject.TryGetComponent<Trigger2DObserver>(out var observer))
            {
                observer = collider.gameObject.AddComponent<Trigger2DObserver>();
            }
            observer.OnTrigger2DStayAct += act;
        }
        /// <summary>
        /// 2D触发器退出
        /// </summary>
        /// <param name="collider"></param>
        /// <param name="act"></param>
        public static void OnTrigger2DExit(this Collider collider, Action<Collider2D> act)
        {
            if (!collider.gameObject.TryGetComponent<Trigger2DObserver>(out var observer))
            {
                observer = collider.gameObject.AddComponent<Trigger2DObserver>();
            }
            observer.OnTrigger2DExitAct += act;
        }
        #endregion

        #region ImgDrag
        /// <summary>
        /// 图片开始拖拽
        /// </summary>
        /// <param name="img"></param>
        /// <param name="act"></param>
        public static void OnBeginDrag(this Image img, Action<PointerEventData> act)
        {
            if (!img.gameObject.TryGetComponent<DragObserver>(out var observer))
            {
                observer = img.gameObject.AddComponent<DragObserver>();
            }
            observer.OnBeginDragAct += act;
        }
        /// <summary>
        /// 图片拖拽中
        /// </summary>
        /// <param name="img"></param>
        /// <param name="act"></param>
        public static void OnDrag(this Image img, Action<PointerEventData> act)
        {
            if (!img.gameObject.TryGetComponent<DragObserver>(out var observer))
            {
                observer = img.gameObject.AddComponent<DragObserver>();
            }
            observer.OnDragAct += act;
        }
        /// <summary>
        /// 图片结束拖拽
        /// </summary>
        /// <param name="img"></param>
        /// <param name="act"></param>
        public static void OnEndDrag(this Image img, Action<PointerEventData> act)
        {
            if (!img.gameObject.TryGetComponent<DragObserver>(out var observer))
            {
                observer = img.gameObject.AddComponent<DragObserver>();
            }
            observer.OnEndDragAct += act;
        }
        #endregion

        #region MouseClick
        /// <summary>
        /// 鼠标按下
        /// </summary>
        /// <param name="go"></param>
        /// <param name="act"></param>
        public static void OnMouseDown(this GameObject go, Action act)
        {
            if (!go.TryGetComponent(out MouseClickObserver obs))
            {
                obs = go.AddComponent<MouseClickObserver>();
            }
            obs.OnMouseDownAct += act;
        }
        /// <summary>
        /// 鼠标抬起
        /// </summary>
        /// <param name="go"></param>
        /// <param name="act"></param>
        public static void OnMouseUp(this GameObject go, Action act)
        {
            if (!go.TryGetComponent(out MouseClickObserver obs))
            {
                obs = go.AddComponent<MouseClickObserver>();
            }
            obs.OnMouseUpAct += act;
        }
        /// <summary>
        /// 鼠标作为按钮抬起
        /// </summary>
        /// <param name="go"></param>
        /// <param name="act"></param>
        public static void OnMouseUpAsButton(this GameObject go, Action act)
        {
            if (!go.TryGetComponent(out MouseClickObserver obs))
            {
                obs = go.AddComponent<MouseClickObserver>();
            }
            obs.OnMouseDownAct += act;
        }
        /// <summary>
        /// 鼠标拖拽
        /// </summary>
        /// <param name="go"></param>
        /// <param name="act"></param>
        public static void OnMouseDrag(this GameObject go, Action act)
        {
            if (!go.TryGetComponent(out MouseClickObserver obs))
            {
                obs = go.AddComponent<MouseClickObserver>();
            }
            obs.OnMouseDragAct += act;
        }
        #endregion

        #region PointerClick
        /// <summary>
        /// img按下
        /// </summary>
        /// <param name="img"></param>
        /// <param name="act"></param>
        public static void OnPointerDown(this Image img, Action<PointerEventData> act)
        {
            if (!img.gameObject.TryGetComponent<PointerObserver>(out var observer))
            {
                observer = img.gameObject.AddComponent<PointerObserver>();
            }
            observer.OnPointerDownAct += act;
        }
        /// <summary>
        /// img抬起
        /// </summary>
        /// <param name="img"></param>
        /// <param name="act"></param>
        public static void OnPointerUp(this Image img, Action<PointerEventData> act)
        {
            if (!img.gameObject.TryGetComponent<PointerObserver>(out var observer))
            {
                observer = img.gameObject.AddComponent<PointerObserver>();
            }
            observer.OnPointerUpAct += act;
        }
        /// <summary>
        /// img点击
        /// </summary>
        /// <param name="img"></param>
        /// <param name="act"></param>
        public static void OnPointerClick(this Image img, Action<PointerEventData> act)
        {
            if (!img.gameObject.TryGetComponent<PointerObserver>(out var observer))
            {
                observer = img.gameObject.AddComponent<PointerObserver>();
            }
            observer.OnPointerClickAct += act;
        }
        #endregion

        #region PointerEE
        /// <summary>
        /// Pointer进入
        /// </summary>
        /// <param name="img"></param>
        /// <param name="act"></param>
        public static void OnPointerEnter(this Image img, Action<PointerEventData> act)
        {
            if (!img.gameObject.TryGetComponent<PointerEEObserver>(out var observer))
            {
                observer = img.gameObject.AddComponent<PointerEEObserver>();
            }
            observer.OnPointerEnterAct += act;
        }
        /// <summary>
        /// Pointer离开
        /// </summary>
        /// <param name="img"></param>
        /// <param name="act"></param>
        public static void OnPointerExit(this Image img, Action<PointerEventData> act)
        {
            if (!img.gameObject.TryGetComponent<PointerEEObserver>(out var observer))
            {
                observer = img.gameObject.AddComponent<PointerEEObserver>();
            }
            observer.OnPointerExitAct += act;
        }
        #endregion

        #region MouseTrigger
        /// <summary>
        /// 鼠标进入
        /// </summary>
        /// <param name="go"></param>
        /// <param name="act"></param>
        public static void OnMouseEnter(this GameObject go, Action act)
        {
            if (!go.TryGetComponent(out MouseTriggerObserver obs))
            {
                obs = go.AddComponent<MouseTriggerObserver>();
            }
            obs.OnMouseEnterAct += act;
        }
        /// <summary>
        /// 鼠标悬浮
        /// </summary>
        /// <param name="go"></param>
        /// <param name="act"></param>
        public static void OnMouseOver(this GameObject go, Action act)
        {
            if (!go.TryGetComponent(out MouseTriggerObserver obs))
            {
                obs = go.AddComponent<MouseTriggerObserver>();
            }
            obs.OnMouseOverAct += act;
        }
        /// <summary>
        /// 鼠标离开
        /// </summary>
        /// <param name="go"></param>
        /// <param name="act"></param>
        public static void OnMouseExit(this GameObject go, Action act)
        {
            if (!go.TryGetComponent(out MouseTriggerObserver obs))
            {
                obs = go.AddComponent<MouseTriggerObserver>();
            }
            obs.OnMouseExitAct += act;
        }
        #endregion

        #region UnityLifeTime
        /// <summary>
        /// GameObject Awake
        /// </summary>
        /// <param name="go"></param>
        /// <param name="act"></param>
        public static void OnAwake(this GameObject go, Action act)
        {
            if (!go.TryGetComponent(out LifeTimeObserver obs))
            {
                obs = go.AddComponent<LifeTimeObserver>();
            }
            obs.OnAwakeAct += act;
        }
        /// <summary>
        /// GameObject OnEnable
        /// </summary>
        /// <param name="go"></param>
        /// <param name="act"></param>
        public static void OnEnable(this GameObject go, Action act)
        {
            if (!go.TryGetComponent(out LifeTimeObserver obs))
            {
                obs = go.AddComponent<LifeTimeObserver>();
            }
            obs.OnEnableAct += act;
        }
        /// <summary>
        /// GameObject OnStart
        /// </summary>
        /// <param name="go"></param>
        /// <param name="act"></param>
        public static void OnStart(this GameObject go, Action act)
        {
            if (!go.TryGetComponent(out LifeTimeObserver obs))
            {
                obs = go.AddComponent<LifeTimeObserver>();
            }
            obs.OnStartAct += act;
        }
        /// <summary>
        /// GameObject OnFixedUpdate
        /// </summary>
        /// <param name="go"></param>
        /// <param name="act"></param>
        public static void OnFixedUpdate(this GameObject go, Action act)
        {
            if (!go.TryGetComponent(out LifeTimeObserver obs))
            {
                obs = go.AddComponent<LifeTimeObserver>();
            }
            obs.OnFixedUpdateAct += act;
        }
        /// <summary>
        /// GameObject Update
        /// </summary>
        /// <param name="go"></param>
        /// <param name="act"></param>
        public static void OnUpdate(this GameObject go, Action act)
        {
            if (!go.TryGetComponent(out LifeTimeObserver obs))
            {
                obs = go.AddComponent<LifeTimeObserver>();
            }
            obs.OnUpdateAct += act;
        }
        /// <summary>
        /// GameObject LateUpdate
        /// </summary>
        /// <param name="go"></param>
        /// <param name="act"></param>
        public static void OnLateUpdate(this GameObject go, Action act)
        {
            if (!go.TryGetComponent(out LifeTimeObserver obs))
            {
                obs = go.AddComponent<LifeTimeObserver>();
            }
            obs.OnLateUpdateAct += act;
        }
        /// <summary>
        /// GameObject Disable
        /// </summary>
        /// <param name="go"></param>
        /// <param name="act"></param>
        public static void OnDisable(this GameObject go, Action act)
        {
            if (!go.TryGetComponent(out LifeTimeObserver obs))
            {
                obs = go.AddComponent<LifeTimeObserver>();
            }
            obs.OnDisableAct += act;
        }
        /// <summary>
        /// GameObject Destroy
        /// </summary>
        /// <param name="go"></param>
        /// <param name="act"></param>
        public static void OnDestroy(this GameObject go, Action act)
        {
            if (!go.TryGetComponent(out LifeTimeObserver obs))
            {
                obs = go.AddComponent<LifeTimeObserver>();
            }
            obs.OnDestroyAct += act;
        }
        #endregion
    }
}